<?php

/**
 * 十三水棋牌游戏控制流程
 * User: liamu
 * Date: 2017/12/13
 * Time: 10:17
 * 注意 详细积分表使用t_historyscore，不再使用t_score_detailed
 * 十三水的game_id=1
*/
namespace app\game\controller;
use think\Session;
use think\Controller;
use think\Loader;
use think\Db;
use think\Log;
use app\common\model\Member;
class Thirteenwater extends Controller {
	private $gamelockfile;
	public function __construct() {
		parent::__construct();
		//文件锁路径
		define("LOCK_FILE_PATH", ROOT_PATH . "tmp/lock/");
		Loader::import('extend.Game.ThirteenWater');
		$this->ThirteenWater = new \ThirteenWater(array());
	}
	public function Test(){
		$this->ThirteenWater->create(3);
		$this->ThirteenWater->test();
	}
	/**
	 * 获取个人信息
	 * 1.正式环境，必须登录，无需传递参数
	 * 2.测试环境下，没有微信登录获取，需要get方式提交个人账号,才能获取信息
	 * @param [type] account_id 个人账号
	 * @return
	 * success:{"result": 0, "operation": "GetMyInfo", "data": {"id": 5841, "photo": "http://wx.qlogo.cn/mmopen/vi_32/Jstogu0jaTGvHficoHwNh5Tpju1zba2ylIMgHibfCmEyZiaA92qjtP8hQb8EYmSXXibDDD4PV2sLMfXoSPc12dhRsg/0", "cards": 0 } }
	 * fail: {"result":1,"operation":"GetMyInfo","data":""}
	 */
	public function GetMyInfo(){
		header('Access-Control-Allow-Origin:*');  
		// 响应类型  
		header('Access-Control-Allow-Methods:POST');  
		// 响应头设置  
		header('Access-Control-Allow-Headers:x-requested-with,content-type');
		header('Access-Control-Allow-Methods:GET'); 
		$id= Session::get('member_id');
		if(!$id){
			$id=isset($_GET['account_id'])?($_GET['account_id']+0):0;
		}
		$result['result']=1;
		$result['operation']='GetMyInfo';
		$result['data']='';
		if($id){
			$member=$this->IsMember($id,'id,game_id,photo,cards,nickname,room_id');
			if(!$member)return json_encode($result);
			$member->nickname=@base64_decode($member->nickname);
			$room = model('room')->where(['id'=>$member->room_id])->field('room_number')->find();
			if($room){
				$member->room_number=$room->room_number;
			}
			if($member){
				$result['result']=0;
				$result['data']=$member;
			}
		}
		return json_encode($result);
	}
	/**
	 * 创建房间，成功后。初始化自己的状态account_status=0 online_status=1 room_id=room->id account_score=0 （积分清零） 扣房卡  jointime=time()   sort=1（ 座位设为1）
	 * 返回 当前局数(game_num) 总局数(playcount)  玩法 (game_type)
	 * room_status 房间游戏状态 0：准备好  1：发牌  2：
	 * islock   准备好的（坐下）人员是否已经满的状态  0：为锁定  1 锁定；坐下时，判断准备好的是否>=4，如过满则islock=1,站起时则islock=0;
	 *  @param
	 * $postData=[
	 *     'account_id'=>,//会员id
	 *     'operation'=>'CreateRoom',
	 *     'data'=>[
	 *                 'ticket_type'=>,//房卡模式：1:40金币10局 2:60金币15局  3:80金币20局  4:120金币30局
	 *                 'game_type'=>,//玩法  1：无特殊牌型  2：有特殊牌型 
	 *                 'banker_mode'=>,//1：通比模式 2：庄家模式  目前只要通比模式
	 *             ],
	 *     ]
	 * @return 
	 * scucess:{"operation": "CreateRoom", "result": 0, "result_message": "创建房间", "data": {"room_id": "375583", "room_number": "1b0q2r50vlg", "playcount": 10, "game_num": 0, "banker_mode": 1, "game_type": 1 }, "players": [{"id": 5840, "nickname": "丑男来了", "photo": "http://wx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTJhibVwX1zg8ibgPxfzPy03eEbwlCiamRDyrD34ic90Igm0YEpTReiaeS2dM4FicopKIxXjuFBufiaRB4e5A/0", "online_status": 1, "account_status": 0, "account_score": 0, "sort": 0, "jointime": 1513824411, "cards_info": [] } ] }
	 * fail:$result=['result'=>1,'result_message'=>'创建失败']
	 *     $result=['result'=>1,'result_message'=>'房卡不足']
	 *     $result=['result'=>1,'result_message'=>'无效信息']
	 */
	public function CreateRoom(){
		$dataPost=$this->GetPost();
		if(!$dataPost){
			return $this->ErrorInfo('CreateRoom','无效信息');
		}
		//判断是否是会员
		$memberInfo = $this->IsMember($dataPost['account_id'],'cards');
		if(!$memberInfo){
			return $this->ErrorInfo('CreateRoom','无效信息');
		}
		// 判断房卡是否足够
		if(isset($dataPost['data']['ticket_type'])){
			$ticket_type=$dataPost['data']['ticket_type'];
			$cards=$this->GetGameCards();
			if(array_key_exists($ticket_type,$cards)){
				if($memberInfo->cards > $cards[$ticket_type]){
					$result = $this->RoomCreate($dataPost);
					$players=$this->GetOlinePlayerInfo($result['data']['room_id']);
					$result['players']=$players;
					// Log::record($result);
					return json_encode($result);
				}
			}
		}
		return $this->ErrorInfo('CreateRoom','房卡不足');
	}
	/**
	 * 第一次点链接进入房间，更新自己状态account_status=0 online_status=1 jointime  room_id，如果是第二次点击进入则指更新 online_status=1  jointime 
	 *  返回申请加入房间的信息 当前局数  总局数 玩法 玩家:id 昵称 头像  积分 account_status 列表返回加入成功。
	 *  房间内准备好的人大于等于4人，锁定房间，但是曾经进入房间的人可以再次进来围观
	 *  account_status（自己的游戏状态） 0：准备 2：坐下 3：发牌    8：游戏结束
	 *  游戏总次数玩完，再次进入则会直接返回战绩列表
	 * @param 
	 * $postData=[
	 *     'account_id'=>,//会员id
	 *     'operation'=>'PrepareJoinRoom',
	 *     'data'=>['room_number'=>],//房间号
	 *     ]
	 * ]
	 * @return 如果游戏没有结束则返回
	 * success: {"result": 0, "account_id": 5841, "operation": "PrepareJoinRoom", "players": [{"id": 5841, "nickname": "休闲时间", "photo": "http://wx.qlogo.cn/mmopen/vi_32/Jstogu0jaTGvHficoHwNh5Tpju1zba2ylIMgHibfCmEyZiaA92qjtP8hQb8EYmSXXibDDD4PV2sLMfXoSPc12dhRsg/0", "online_status": 1, "account_status": 0, "account_score": 240, "sort": null, "jointime": 1513763234, "cards_info": [] } ], "data": {"room_status": 2, "room_number": "3206944", "playcount": 10, "game_num": 7, "banker_mode": 2, "game_type": 5, "ticket_type": 1 }, "result_message": "围观"}
	 * 
	 * faile: ['result'=>1,'operation'=>'PrepareJoinRoom','result_message'=>'房间人数已满！']
	 *     ['result'=>1,'operation'=>'PrepareJoinRoom','result_message'=>'无效信息']
	 * @return 如果游戏结束则返回战绩列表
	 *  success:  {"result": 0, "account_id": 5841, "operation": "GameOver", "data": [{"nickname": "休闲时间", "photo": "http://wx.qlogo.cn/mmopen/vi_32/Jstogu0jaTGvHficoHwNh5Tpju1zba2ylIMgHibfCmEyZiaA92qjtP8hQb8EYmSXXibDDD4PV2sLMfXoSPc12dhRsg/0", "score": 240 }, {"nickname": "丑男来了", "photo": "http://wx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTJhibVwX1zg8ibgPxfzPy03eEbwlCiamRDyrD34ic90Igm0YEpTReiaeS2dM4FicopKIxXjuFBufiaRB4e5A/0", "score": -80 } ] }
	 *  faile: {"result": 1, "operation": "GameOver", "result_message": "游戏结束"}
	 */
	public function PrepareJoinRoom(){
		$dataPost=$this->GetPost('PrepareJoinRoom');
		if(!$dataPost){
			return $this->ErrorInfo('PrepareJoinRoom','无效信息');
		}
		//1. 判断是否是会员
		$member = $this->IsMember($dataPost['account_id'],'id,room_id');
		if(!$member){
			return $this->ErrorInfo('PrepareJoinRoom','无效信息');
		}
		//2. 判断房间是否存在,游戏总次数是否结束，是否锁定
		$room=$this->RoomIsExist($dataPost);
		$detail=Db::table('t_historyscore')->where(['account_id' =>$dataPost['account_id'],'room_id'=>$room->id])->find();
		if(!$room){
			return $this->ErrorInfo('PrepareJoinRoom','无效信息');
		}elseif($room->playcount==$room->game_num){//游戏已经结束返回游戏战绩
			return $this->GetMembersScore($room->id,$member->id);
		}elseif($room->islock==1){
			if($member->room_id != $room->id){//房间锁定并且曾经没有进来过，则返回人满
				return $this->ErrorInfo('PrepareJoinRoom','房间人数已满！');
			}
		}
		// 3. 房间到达4人准备好（account_status>=2）就锁定，并返回false
		$allmember=$this->RoomIsLock($room->id,'id');
		if($allmember===false){
			if($member->room_id != $room->id){//如果曾来过房间，还是可以再次进来
				return $this->ErrorInfo('PrepareJoinRoom','房间人数已满！');
			}
		}
		// 4.初始化自己进入房间后的状态
		if($member->room_id==$room->id){//第二次进入
			$data=['online_status'=>1,'jointime'=>time()];
		}else{//第一次进入
			$data=['room_id'=>$room->id,'online_status'=>1,'account_status'=>0,'jointime'=>time(),'sort'=>null,'game_id'=>1];
		}
		$this->UpdateMemberById($data,$member->id);
		// 5. 获取房间内在线的或者离线后台玩的所有人的id,nickname,jointime,sort
		$players=$this->GetOlinePlayerInfo($room->id);
		// 6. 返回进房询问结果
		$result['result'] = 0;
		$result['account_id'] = $dataPost['account_id'];
		$result['operation'] = "PrepareJoinRoom";
		$result['players'] = $players;// 选手信息
		// 房间的的游戏信息
		$result['data']['account_id']=$room->account_id;
		$result['data']['room_id'] = $room->id;
		$result['data']['room_status'] = $room->room_status;
		$result['data']['roomStatus']=$room->roomStatus;
		$result['data']['room_number'] = $room->room_number;
		$result['data']['playcount'] = $room->playcount;
		$result['data']['game_num']=$room->game_num;
		$result['data']['banker_mode']=$room->banker_mode;
		$result['data']['game_type']=$room->game_type;
		$result['data']['ticket_type'] = $room->ticket_type;
		$result['result_message'] = "围观";
		return json_encode($result);
	} 
	/**
	 * 坐下:准备好开始游戏， 更新 online_status=1  account_status=2 account_score  score_board 如果房间没用房主，则坐下的人成为房主
	 * 返回坐下的信息 当前局数  总局数 玩法 玩家:id 昵称 头像  积分 account_status 列表返回坐下成功。
	 * workman 发消息给房主，要求开始
	 *@param 
	 * dataPost=[
	 *     'account_id'=>,//会员账号
	 *     'operation'=>'SitDown',
	 *     'data'=>[
	 *         'room_id'=>,//房间id
	 *         'sort'=>//座位 （1  2  3  4）
	 *     ]
	 * ]
	 * @return 
	 * successs: {"result": 0, "operation": "SitDown", "data": {"total_num": 20, "room_id": 375561, "room_number": "9977070", "room_status": 2, "game_num": 6 }, "players": [{"id": 6695, "nickname": "杰仔", "photo": "http://wx.qlogo.cn/mmopen/vi_32/Ff0KhcfAB9oesIx1fu869HVVAicoiaNq5t3vCFNT6cfxKdVBKkpVplnY38KpxSmvp3NKazulhlxOkicpNWNgI13nQ/0", "online_status": 0, "account_status": 3, "account_score": 350, "sort": null, "jointime": null, "cards_info": ["D7", "A4", "C3", "C11", "A3", "A10", "A12", "B3", "B2", "D1", "C1", "C9", "B10"] }, {"id": 5840, "nickname": "丑男来了", "photo": "http://wx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTJhibVwX1zg8ibgPxfzPy03eEbwlCiamRDyrD34ic90Igm0YEpTReiaeS2dM4FicopKIxXjuFBufiaRB4e5A/0", "online_status": 1, "account_status": 2, "account_score": 0, "sort": 1, "jointime": 1513757404, "cards_info": [] } ], "result_message": "坐下，准备好！"}
	 * faile: ['result'=>1,'operation'=>'SitDown','result_message'=>'房间人数已满！']
	 *    ['result'=>1,'operation'=>'SitDown','result_message'=>'无效信息']
	 */
	public function SitDown(){
		$dataPost=$this->GetPost('SitDown');
		if(!$dataPost or !isset($dataPost['data']['sort'])){
			return $this->ErrorInfo('SitDown','无效信息1');
		}
		//1.座位号错误
		if($dataPost['data']['sort']<0 or $dataPost['data']['sort']>4){
			return $this->ErrorInfo('SitDown','座位号错误');
		}
		//2.判断是否是会员
		$member = $this->IsMember($dataPost['account_id'],'id');
		if(!$member){
			return $this->ErrorInfo('SitDown','无效信息2');
		}
		//3.判断房间是否存在,
		$room=$this->RoomIsExist($dataPost);
		if(!$room){
			return $this->ErrorInfo('SitDown','无效信息3');
		}
		//如果房间没有房主，则成为房主
		if(empty($room->account_id)){
			$this->UpdateRoomById(['account_id'=>$member->id],$room->id);
		}
		// 3. 房间准备好的人以及在玩的人等于4人就锁定，返回false，否则取得准备好人员的sort的信息
		$allmember=$this->RoomIsLock($room->id,'id,sort');
		if($allmember===false){
			return $this->ErrorInfo('SitDown','房间人数已满！');
		}
		// 4. 验证座位号是否被占用
		$sorts=array_column($allmember,'sort');
		if(in_array($dataPost['data']['sort'], $sorts)){
			//座位号错误
			return $this->ErrorInfo('SitDown','此座位号已被占用');
		}
		// 5. 查询积分，初始化个人积分
		$detail=Db::table('t_historyscore')->where(['account_id' =>$dataPost['account_id'],'room_id'=>$room->id])->find();
		$myScore=0;
		if($detail)$myScore=$detail['score'];
		// 6. 更新个人状态
		$data=['online_status'=>1, 'score_board'=>$myScore, 'account_score'=>$myScore, 'account_status'=>2, 'sort'=>$dataPost['data']['sort'], ];
		if($dataPost['data']['room_id'] != $member->id){
			$data['room_id']=$room->id;
		}
		$this->UpdateMemberById($data,$member->id);
		// 7. 获取房间内在线的或者离线后台玩的所有人的id,nickname,jointime,sort
		$players=$this->GetOlinePlayerInfo($room->id);
		// 返回准备好的信息
		$result['result'] = 0;
		$result['operation'] = "SitDown";
		$result['data']['total_num'] = $room['total_num'];
		$result['data']['account_id'] = $room['account_id'];
		$result['data']['roomStatus'] = $room['roomStatus'];//roomStatus=0则显示开始按钮
		$result['data']['room_id'] = $room['id'];
		$result['data']['room_number'] = $room['room_number'];
		$result['data']['room_status'] = $room['room_status'];
		$result['data']['game_num'] = $room['game_num'];
		$result['players']=$players;
		$result['result_message'] = "坐下，准备好！";
		return json_encode($result);
	} 
	/**
	 * 站起：如果游戏结束，状态为 8时，可以站起，否则不可以。如果房主站起，则将房主转给下一个人,没有其他人则account_id=0
	 * 站起后更新 account_status=0 sort=null 如果 t_room 中islock=1 则改为0
	 * @param dataPost=[
	 *     'account_id'=>,//会员账号
	 *     'operation'=>'StandUp',
	 *     'data'=>[
	 *         'room_id'=>,//房间id
	 *     ]
	 * ]
	 * @return
	 * success:{"result": 0, "operation": "StandUp", "data": {"total_num": 20, "room_id": 375561, "room_number": "9977070", "room_status": 2, "game_num": 6 }, "players": [{"id": 6695, "nickname": "杰仔", "photo": "http://wx.qlogo.cn/mmopen/vi_32/Ff0KhcfAB9oesIx1fu869HVVAicoiaNq5t3vCFNT6cfxKdVBKkpVplnY38KpxSmvp3NKazulhlxOkicpNWNgI13nQ/0", "online_status": 0, "account_status": 3, "account_score": 350, "sort": null, "jointime": null, "cards_info": ["D7", "A4", "C3", "C11", "A3", "A10", "A12", "B3", "B2", "D1", "C1", "C9", "B10"] }, {"id": 6737, "nickname": "小磊", "photo": "http://wx.qlogo.cn/mmopen/vi_32/AR6UTBhqOpOkYvEOkQUEgUS3JZetXcF0nDBeJ10gfxNDD2tHTAx1X54eRY6AJOFhXaPT0xhGD5Cx3Qg5mgU7EQ/0", "online_status": 1, "account_status": 3, "account_score": -85, "sort": null, "jointime": null, "cards_info": ["C8", "B12", "B8", "B1", "C2", "B7", "C5", "B13", "D8", "A13", "B6", "B9", "D13"] } ], "result_message": "站起成功！"}
	 * fail:   {"result": 1, "operation": "StandUp", "result_message": "无效信息"} 
	 * 		{"result": 1, "operation": "StandUp", "result_message": "游戏未结束，不能站起！"}
	 */
	public function StandUp(){
		$dataPost=$this->GetPost('StandUp');
		if(!$dataPost){
			return $this->ErrorInfo('StandUp','无效信息');
		}
		//1.判断是否是会员
		$member = $this->IsMember($dataPost['account_id'],'id,account_status');
		if((!$member) or $member->account_status<2 ){
			return $this->ErrorInfo('StandUp','无效信息');
		}
		//2.判断房间是否存在,是否锁定
		$room=$this->RoomIsExist($dataPost);
		if(!$room){
			return $this->ErrorInfo('StandUp','房间不存在');
		}
		//3.判断游戏是否结束，否则不能站起
		if($member->account_status <8 ){
			return $this->ErrorInfo('StandUp','游戏未结束，不能站起！'); 
		}
		//4.修改自己的状态
		$this->UpdateMemberById(['account_status'=>0,'sort'=>null],$member->id);
		// 5. 如果房间是锁定的，则修改房间的锁定状态
		$data=[];
		$allMemberInRoom=$this->GetAllMemeberIdAtRoom($room->id);
		if($room->islock==1){
			$data['islock']=0;
		}
		//6. 如果是房主站起，则将房间所有权转让给下一位游戏者
		if($room->account_id==$member->id){
			$inGameMember=$allMemberInRoom['inGameMember'];
			if(isset($inGameMember[$member->id])){
				unset($inGameMember[$member->id]);
			}
			if(count($inGameMember)>0){
				$inGameMember=array_values($inGameMember);
				$data['account_id']=$inGameMember[0]['id'];
			}else{
				$data['account_id']=null;
			}
		}
		if(!empty($data))$this->UpdateRoomById($data,$room->id);
		$players=$this->GetOlinePlayerInfo($room->id);
		// 7.返回站起成功
		$result['result'] = 0;
		$result['operation'] = "StandUp";
		$result['data']['total_num'] = $room['total_num'];
		$result['data']['room_id'] = $room['id'];
		$result['data']['room_number'] = $room['room_number'];
		$result['data']['room_status'] = $room['room_status'];
		$result['data']['game_num'] = $room['game_num'];
		$result['players']=$players;
		$result['result_message'] = "站起成功！";
		return json_encode($result);
	}
	/**
	 * 获得所有玩家信息
	 * @param 
	 * dataPost=[
	 *     'account_id'=>,//会员账号
	 *     'data'=>[
	 *         'room_id'=>,//房间id
	 *     ]
	 * ]
	 * @return
	 *sucssee:{"result": 0, "operation": "AllGamerInfo", "data": [{"id": 6695, "nickname": "杰仔", "cards_info": ["D7", "A4", "C3", "C11", "A3", "A10", "A12", "B3", "B2", "D1", "C1", "C9", "B10"], "account_status": 3, "online_status": 1, "sort": 1, "jointime": 1513581353 }, {"id": 5840, "nickname": "丑男来了", "cards_info": [], "account_status": 2, "online_status": 1, "sort": null, "jointime": null } ], "result_message": "所有玩家状态"}
	 *fail:['result'=>1,'operation'=>'AllGamerInfo','result_message'=>'无效信息']
	 */
	public function AllGamerInfo(){
		$dataPost=$this->GetPost('AllGamerInfo');
		if(!$dataPost){
			return $this->ErrorInfo('AllGamerInfo','无效信息');
		}
		//判断是否是会员
		$member = $this->IsMember($dataPost['account_id'],'*');
		if(!$member){
			return $this->ErrorInfo('AllGamerInfo','无效信息');
		}
		$room = model('room')->where(array('id' => $dataPost['data']['room_id']))->find();
		if(!$room){
			return $this->ErrorInfo('AllGamerInfo','房间不存在');
		}
		// 取得在房间内所有在线人员的信息，判断是否在线online_status
		$id=$room->id;
		$allMemberInRoom = Db::query("select id,nickname,cards_info,account_status,online_status,sort,jointime from t_member where room_id =$id order by sort asc,jointime asc");
		foreach ($allMemberInRoom as $key => $val) {
			$allMemberInRoom[$key]['nickname']=@base64_decode($val['nickname']);
			$allMemberInRoom[$key]['cards_info']=empty($val['cards_info'])? array() : @unserialize($val['cards_info']);
		}
		$result['result'] = 0;
		$result['operation'] = "AllGamerInfo";
		$result['data'] = $allMemberInRoom;
		$result['result_message'] = "所有玩家状态";
		return json_encode($result);
	} 
	/**
	 * 游戏第一局必须是房主点击开始按钮，游戏开始：发牌(在线的人只要有两人准备好了，且房主点击开始了才发牌并保存到cards_info字段里)修改starttime=time()，将牌信息返回给相应的人
	 * @param 
	 * dataPost=[
	 *     'account_id'=>,//会员账号
	 *     'operation'=>'GameStart',
	 *     'data'=>[
	 *         'room_id'=>,//房间id
	 *     ]
	 * ]
	 * @return
	 * success: {"result": 0, "operation": "GameStart", "data": {"account_id": 6695, "room_id": 375561, "account_status": 2, "online_status": 0, "limit_time": 60 }, "cards_info": [{"account_id": 6737 }, {"data": ["B3", "D9", "D3", "A3", "D1", "D4", "B9", "D6", "C12", "B11", "B12", "B8", "A10"] }, {"prompt": ["乌龙", "乌龙", "乌龙"] }, {"isspecial": "false"}, {"score": 0 }, {"account_id": 6738 }, {"data": ["B5", "A11", "C9", "A9", "D13", "B4", "A1", "B7", "A12", "D10", "C2", "A13", "B10"] }, {"prompt": ["乌龙", "乌龙", "乌龙"] }, {"isspecial": "false"}, {"score": 0 } ], "result_message": "游戏开始了"}
	 * fail:
	 */
	public function GameStart(){
	  /*****1.接收验证数据*******/
		$dataPost=$this->GetPost('GameStart');
		if(!$dataPost){
			return $this->ErrorInfo('GameStart','无效信息');
		}
		//判断是否是会员
		$member = $this->IsMember($dataPost['account_id'],'id,account_status,online_status');
		if(!$member){
			return $this->ErrorInfo('GameStart','无效信息');
		}
		// 判断房间是否存在
		$room = model('room')->where(array('id' => $dataPost['data']['room_id']))->find();
		if(!$room){
			return $this->ErrorInfo('GameStart','房间不存在');
		}
		//判断是否是房主点击的开始
		if($room->account_id != $dataPost['account_id']){
			return $this->ErrorInfo('GameStart','您不是房主');
		}
		//如果房间状态不等于0（0表示准备好），返回false;
		if($room->room_status !=0){
			return $this->ErrorInfo('GameStart','房间状态不对');
		}
	  /*****2.查询同一房间且符合条件的会员id*******/
		$memberInRoom=$this->GetAllMemeberIdAtRoom($room->id);
		$memberIds=$memberInRoom['memberIds'];//在线的
		$allReadyMember=$memberInRoom['allReadyMember'];
		$allReadyMemberInfo=$memberInRoom['allReadyMemberInfo'];
	  /*****3.初始化返回结果*******/
		$result['result'] = 0;
		$result['operation'] = "GameStart";
		$result['data']['account_id'] = $member['id'];
		$result['data']['room_id'] =$room->id;
		$result['data']['account_status'] = $member['account_status'];
		$result['data']['online_status'] = $member['online_status'];
	  /*****4.准备好的人数不够，返回没准备好*******/
		if(count($allReadyMember)<2){
			$result['playercount']=count($allReadyMember);
			$result['result_message'] = "人员还没准备好！";
			return json_encode($result);
		}
		/*****5.修改状态*******/
		// 3.3 更新房间状态
		$game_num=$room->game_num +1;
		//roomStatus=1 则不再显示开始按钮
		$data=['starttime'=>time(),'game_num' => $game_num, 'room_status' => 2,'roomStatus'=>1];
		$this->UpdateRoomById($data,$room->id);
		//3.4发牌
		$paiInfo=$this->ThirteenWater->create(count($allReadyMember));
		// 分别保存到会员表的cards_info里，并修改account_status=3 表示已经发牌
		foreach ($allReadyMemberInfo as $key => $val) {
			$pai=serialize($paiInfo[$key]);
			$allReadyMemberInfo[$key]['cards_info']=$paiInfo[$key];
			$this->UpdateMemberById(['cards_info'=>$pai,'account_status'=>3],$val['id']);
		}
		$players=$this->GetOlinePlayerInfo($room->id,'id,cards_info');
		$cards_info=[];
		foreach ($players as $player) {
			$obj=new \StdClass();
			$obj->account_id=$player['id'];
			$obj->data=$player['cards_info'];
			$obj->prompt=['乌龙','乌龙','乌龙'];
			$obj->isspecial='false';
			$obj->score=0;
			$cards_info[]=$obj;
			unset($obj);
		}
		$result['operation'] = "GameStart";
		$result['data']['limit_time'] = 60;
		$result['cards_info']=$cards_info;
		$result['result_message'] = "游戏开始了";
		return json_encode($result);
	} 
	/**
	 * 游戏自动开始：从第二局，自动发牌给所有在玩牌的人
	 * 
	 */
	public function GameAutoStart(){

	}
	/**
	 * 更新所有玩家信息
	 */
	public function UpdateGamerInfo(){

	} 
	/**
	 * 离线操作，修改用户状态，并在workman中通知其他人
	 * @param 
	 * dataPost=[
	 *     'account_id'=>,//会员账号
	 *     'data'=>[
	 *         'room_id'=>,//房间id
	 *     ]
	 * ]
	 * @return 
	 * success:{"result": 0, "operation": "GetOffLine", "data": {"account_id": 6695, "online_status": 1, "account_status": 3 }, "players": {"memberIds": [6737, 6738, 5840 ], "allReadyMember": [], "allInitMember": [5840 ], "allReadyMemberInfo": [], "inGameMember": {"6695": {"id": 6695, "online_status": 0, "account_status": 3 }, "6737": {"id": 6737, "online_status": 1, "account_status": 3 }, "6738": {"id": 6738, "online_status": 1, "account_status": 3 } } }, "result_message": "用户下线"}
	 * falil:  {"result": 1, "operation": "StandUp", "result_message": "无效信息"} 
	 */
	public function GetOffLine(){
		$dataPost=$this->GetPost('GetOffLine');
		if(!$dataPost){
			return $this->ErrorInfo('GetOffLine','无效信息');
		}
		//判断是否是会员
		$member = $this->IsMember($dataPost['account_id'],'id,account_status,room_id');
		if(!$member){
			return $this->ErrorInfo('GetOffLine','invalid info!');
		}
		//此处不清除member表中的room_id 目的是即使掉线了，后台依旧可以自动发牌，出牌，不影响其他用户玩
		$this->UpdateMemberById(['online_status'=>0],$member->id);
		// 判断房间是否存在
		$room = model('room')->where(array('id' => $member->room_id))->field('id')->find();
		if(!$room){
			return $this->ErrorInfo('GetOffLine','room is not exsits!');
		}
		$players=$this->GetOlinePlayerInfo($room->id);
		$result['result'] = 0;
        $result['operation'] = "GetOffLine";
        $result['data']['room_id']=$room->id;
        $result['data']['account_id'] = $member->id;
        $result['data']['online_status'] = 0;
        $result['data']['account_status'] = $member->account_status;
        $result['players']=$players;
        $result['result_message'] = "用户下线";
        return json_encode($result);
	} 
	/**
	 * 手动出牌：手动点
	 * 1.修改自己的 account_status=7  如果都出牌了，直接返回比牌结果；
	 * 2.如果还有人没用比牌，直接返回自己已出牌，返回已经出牌的人id给在线人员，倒计时等待
	 * 自动出牌：计时器定时出牌
	 * 
	 */
	public function PlayerShowCard(){
		
	}
	/**
	 * 修改所有人的
	 */
	public function AutoShowCard(){

	}
	/**
	 * 游戏结束
	 * 1.每一局的游戏结束：如果当前局数<游戏总局数，修改房间状态room_status=0  end_time 修改玩游戏人员的account_status  account_score, 保存每个人的战绩信息到t_history，汇总战绩结果到 t_historyscore 更新房间人员的信息：game_id=0 (这样刷新页面就会)
	 * 1.1 返回本局游戏结果
	 * 2.总局数结束：如果当前局数=游戏总局数, 修改房间的 end_time 修改玩游戏人员的account_status  保存每个人的战绩信息到t_history，汇总战绩结果到 t_historyscore  
	 * 2.1 返回游戏结束后的 积分排名
	 */
	private function GameOver(){

	}
	/**
	 * 取得相应房间人员内的战绩列表
	 * @param [int] $room_id    [房间号]
	 * @param [int] $account_id [操作人员id]
	 * @return json  返回结果 
	 */
	private function GetMembersScore($room_id,$account_id){
		$details=Db::query("select m.nickname,m.photo,d.score from t_historyscore as d left join t_member as m on (d.room_id={$room_id} and d.account_id=m.id) where d.room_id={$room_id} order by d.score desc");
			if(empty($details)){
				return $this->ErrorInfo('GameOver','游戏结束');
			}
			foreach ($details as $key=> $val) {
				$details[$key]['nickname']=@base64_decode($val['nickname']);
				$details[$key]['score']=$val['score'];
			}
			$result['result'] = 0;
			$result['account_id'] =$account_id;
			$result['operation'] = "GameOver";
			$result['data']=$details;
			return json_encode($result);
	}
	/**
	 * 按座位和加入时间排序，获得在线选手以及离线在玩选手的信息
	 * @param [int] $room_id [房间id]
	 */
	private function GetOlinePlayerInfo($room_id,$field=""){
		if($field=='')$field='id,nickname,photo,online_status,account_status,account_score,sort,jointime,cards_info';
		$all = Db::query("select $field from t_member where room_id =$room_id and ( online_status=1 or account_status>=2 ) order by sort asc ,jointime asc ");
		if(empty($all))$all=[];
		$ret=[];
		foreach ($all as  $val) {
			if(isset($val['nickname'])){
				$val['nickname']=$this->DecodeNickname($val['nickname'],0);
			}
			if(isset($val['cards_info'])){
				$val['cards_info']=empty($val['cards_info'])? array() : @unserialize($val['cards_info']);
			}
			$ret[]=$val;
		}
		return $ret;
	}
	/**
	 * 返回同一房间内所有人的id 状态
	 * @param [type] $room_id [房间id]
	 * @return array $ret  [会员id 在线状态 游戏状态]
	 */
	private function GetAllMemeberIdAtRoom($room_id){
		$all = Db::query("select id,online_status,account_status from t_member where room_id =$room_id order by jointime asc");
		if(empty($all))$all=[];
		
		$memberIds=[];// online_status=1 房间内在线的id
		$allReadyMember=[];// account_status=2的id 无论是否在线，但准备好游戏 人的id
		$allReadyMemberInfo=[];// account_status=2的id 无论是否在线，但准备好游戏 的人的状态信息
		$allInitMember=[];// online_status=1  account_status<2 在线且准备好游戏人的id
		$inGameMember=[];//正在游戏当中
		foreach ($all as  $val) {
			if(!empty($val['nickname'])){
				$val['nickname']=@base64_decode($nickname);
			}
			// 取出符合online_status=1的id
			if($val['online_status']==1){
				$memberIds[]=$val['id'];
			}
			// account_status=2的id 准备好游戏
			if($val['account_status']==2){
				$allReadyMember[]=$val['id'];
				$allReadyMemberInfo[]=$val;
			}
			// 取出符合online_status=1  account_status<2 在线且准备好的id
			if($val['online_status']==1 && ($val['account_status'] <2 )){
				$allInitMember[]=$val['id'];
			}
			//取出所有正在游戏的人
			if($val['account_status']>=2){
				$inGameMember[$val['id']]=$val;
			}
		}
		$ret= [
				'memberIds'=>$memberIds,
				'allReadyMember'=>$allReadyMember,
				'allInitMember'=>$allInitMember,
				'allReadyMemberInfo'=>$allReadyMemberInfo,
				'inGameMember'=>$inGameMember,
			];
		return $ret;
	}
	private function gamelock($roomid) {
		//锁住不让操作，保证原子性
		$this->gamelockfile = fopen(LOCK_FILE_PATH . $roomid, "w");
		flock($this->gamelockfile, LOCK_EX);
	}

	/**
	 * 游戏中使用的文件锁,解锁
	 * @param $roomid
	 * @return bool
	 */
	private function gameunlock($roomid) {
		//锁住不让操作，保证原子性
		flock($this->gamelockfile, LOCK_UN);
		fclose($this->gamelockfile);
	}
	/**
	 * 通过id修改房间信息
	 * @param [type] $data   修改的数组
	 * @param [type] $roomId 房间id
	 */
	private function UpdateRoomById($data,$roomId){
		model('room')->where(array('id' => $roomId))->update($data);
	}
	/**
	 * 通过 member 的 id 更新相应字段
	 * @param [type] $data [相应字段数组]
	 * @param [type] $id   [会员id]
	 */
	private function UpdateMemberById($data,$id){
		db('member')->where('id',$id)->update($data);
	}
	/**
	 * 判断房间是否应该被锁 在线人数大于等于4人就锁定房间
	 * @param [type] $id 房间id
	 * @param [type] $filed 要查询的字段
	 */
	private function RoomIsLock($id,$filed="*"){
		$id+=0;
		$allmember = Db::query("select $filed from t_member where room_id =$id and account_status >=2");
		$allCount = count($allmember);
		if($allCount >= 4){
			$this->LockRoom($id);
			return false;
		}
		return $allmember;
	}
	/**
	 * 判断房间是否存在(可以通过id，或者room_number查询)
	 * @param [array] $data  数组
	 * @return bool false | obj 房间对象
	 */
	private function RoomIsExist($post){
		//判断房间是否存在
		if(isset($post['data']['room_id'])){
			$where=['id' => $post['data']['room_id']];
		}elseif(isset($post['data']['room_number'])){
			$where=['room_number' => $post['data']['room_number']];
		}else{
			return false;
		}
		$room = model('room')->where($where)->find();
		if($room){
			return $room;
		}
		return false;
	}
	/**
	 * 返回id对应人的某些字段数据
	 * @param int $id    [会员账号id]
	 * @param string $field 字段字符串
	 * @return obj $member  会员信息   | bool  false
	 */
	private function IsMember($id,$field='*'){
		//判断是否是会员
		if($field=='*'){
			$member = model('member')->where(['id' =>$id])->find();
		}else{
			$member = model('member')->where(['id' =>$id])->field($field)->find();
		}
		if(!$member)return false; 
		return $member;
	}
	/**
	 * 将昵称解码
	 * @param [type]  $nicknames [昵称]
	 * @param integer $isArray   [是否是数组的标识]
	 */
	private function DecodeNickname($nicknames,$isArray=0){
		if($isArray){
			$result=[];
			foreach ($nicknames as $nickname) {
				$result[]=@base64_decode($nickname);
			}
			return $result;
		}else{
			$result=@base64_decode($nicknames);
			return $result;
		}
	}
	/**
	 * 乐观锁锁定房间，不准再让人坐下，准备开始玩
	 * @param [type] $id [房间id]
	 */
	private function LockRoom($id){
		model('room')->where(['id' => $id])->update(['islock' => 1]);
	}
	/**
	 * 取出提交的数据
	 * @param  post提交的数据
	 * @return array | false 
	 */
	private function GetPost($flag='createroom'){
		$dataPost = json_decode(file_get_contents('php://input'), true);
		if(!isset($dataPost['account_id'])){// POST提交
			//点击链接Get传入参数
			if(isset($_GET['account_id']) && isset($_GET['room_number'])){
				$dataPost['account_id']=$_GET['account_id']+0;
				$dataPost['data']['room_number']=$_GET['room_number'];
			}else{
				return false;
			}
		}
		Log::record(date("Y-m-d H:i:s").' '.$flag.':');
		Log::record($dataPost);
		if(is_array($dataPost)){
			if(isset($dataPost['account_id'])){
				// 开通验证session验证
				if(Session::has('member_id')){
					$member_id = Session::get('member_id');
					if($member_id !=$dataPost['account_id']){
						return false;
					}
				}
				return $dataPost;
			} 
		}
		return false;
	}
	/**
	 * 返回错误信息
	 * @param [type]  $operation  [方法名]
	 * @param [type]  $message    [要返回的信息]
	 * @param integer $res        [返回结果]
	 */
	private function ErrorInfo($operation,$message,$res=1){
		$result['result'] =$res ;
		$result['operation'] = $operation;
		$result['result_message'] = $message;
		return json_encode($result);
	}
	/**
	 * 获得ticke_type对应的游戏局数参数数组
	 */
	private function GetGameNums()
	{
		return [1=>10,2=>15,3=>20,4=>30];
	}
	/**
	 * 获得ticke_type对应的消耗的金币说参数数组
	 */
	private function GetGameCards(){
		return [1=>40,2=>60,3=>80,4=>120];
	}
	/**
	 * 新增一个房间 成功后，扣房卡，更改自己的状态 account_status=0 online_status=1 room_id
	 * @param [type] $post [post提交的数据]
	 * @return [array]$result 返回结果
	 */
	private function RoomCreate($post){
		// 初始化参数
		$result = [];
		$num=$this->GetGameNums();//游戏次数数组
		$card=$this->GetGameCards();//游戏扣的房卡数组
		$ticket_type=$post['data']['ticket_type'];//前端传的房卡索引

		$result['operation'] = "CreateRoom";
		$result['result'] = 1;
		$result['result_message'] = "创建失败";
		if(!array_key_exists($ticket_type, $card)){
			return $result;
		}
		//房间号 时间戳加6位随机数，随后变成32进制字符串
		$data['room_number'] = time().rand(100000,999999);
		$data['room_number']=base_convert ($data['room_number'],10,32);
		// 添加数据
		$dbroom=model('room');
		$data['account_id'] = $post['account_id'];
		$data['room_cards_num']=$card[$ticket_type];
		$data['ticket_type'] = $ticket_type; 
		$data['playcount']=$num[$ticket_type];
		$data['banker_mode'] = 1; //通比模式
		$data['room_status'] = 0;//房间的游戏状态，0未开始，1准备
		$data['game_num']=0;//游戏次数
		$data['islock']=0;//游戏开始后则锁定为1
		if(isset($post['data']['game_type'])&& ($post['data']['game_type']>0 && $post['data']['game_type']<4)){
			$data['game_type']=$post['data']['game_type'];
		}else{
			$data['game_type']=1;//默认无特殊模式
		}
		$data['starttime']=time();
		$ret=$dbroom->save($data);
		if(!$ret){
			return $result;
		}
		//开房间扣金币,更新自己的房间号码
		$member=Member::get($post['account_id']);
		$member->cards=($member->cards - $card[$ticket_type]);
		$member->room_id=$dbroom->id;
		$member->online_status=1;
		$member->account_status=0;
		$member->jointime=time();
		$member->sort=0;
		$member->account_score=0;//积分清零
		$member->game_id=1;//游戏是十三水的id
		$member->save();
		// 返回成功结果
		$result['result'] = 0;
		$result['data']['room_id'] = $dbroom->id;
		$result['data']['room_number'] = $data['room_number'];
		$result['data']['playcount'] = $dbroom->playcount;
		$result['data']['game_num']=$dbroom->game_num;
		$result['data']['banker_mode']=$dbroom->banker_mode;
		$result['data']['game_type']=$dbroom->game_type;
		$result['result_message'] = "创建房间";
		return $result;
	}

 }
